package com.tangdi.production.mpaychl.controller.third;

import com.acq.sdk.AlipayConfig;
import com.alipay.api.internal.util.AlipaySignature;
import com.tangdi.production.mpaychl.service.impl.wxpay.utils.XMLUtil;
import com.tangdi.production.mpbase.constants.ExcepCode;
import com.tangdi.production.mpbase.constants.MsgCT;
import com.tangdi.production.mpbase.exception.BusinessException;
import com.tangdi.production.mpbase.service.OrderService;
import com.tangdi.production.mpbase.util.MoneyUtils;
import com.tangdi.production.mpbase.util.ObjectUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.*;

/**
 * H5接口回调
 * @author T_BUG
 */
@Controller
@RequestMapping("H5-wxpay")
public class H5WXController {
	private static final Logger logger = LoggerFactory.getLogger(H5WXController.class);
	
	@Autowired
	private OrderService orderService;
	
	@ResponseBody
	@RequestMapping(value={"/return-url"},method={RequestMethod.GET})
	public String returnUrl(HttpServletRequest request, HttpServletResponse response){
		logger.info("[前端回调]获取微信GET过来反馈信息");
		try {
			//获取支付宝GET过来反馈信息
			Map<String,String> params = new HashMap<String,String>();
			Map requestParams = request.getParameterMap();
			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i]
							: valueStr + values[i] + ",";
				}
				//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
				params.put(name, valueStr);
			}
			
			//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
			//商户订单号
			String prdOrdNo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
			if(StringUtils.isEmpty(prdOrdNo)){
				throw new BusinessException(ExcepCode.EX900000,"回调订单号为空");
			}
			
			//支付宝交易号
			String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
			
			//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
			//计算得出通知验证结果
			//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
			boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
			
			if(verify_result){//验证成功
				logger.info("前端回调验签通过");
				
			}else{
				logger.error("前端回调验签失败:{}", requestParams);
			}
		} catch (Exception e){
			logger.error("前端回调异常:{}", e.getMessage(), e);
			return "ERROR";
		}
		logger.info("前端回调完成");
		return "SUCCESS";
	}

	@RequestMapping(value={"/notify-url"},method={RequestMethod.POST})
	public void notifyUrl(HttpServletRequest request, HttpServletResponse response){
		
		logger.info("[异步回调]获取微信POST过来反馈信息");
		
		try {
			System.out.println("进入支付h5回调=====================");
			String xmlMsg = readData(request);
			System.out.println("pay notice---------"+xmlMsg);
			Map params = XMLUtil.doXMLParse(xmlMsg);

			try {
				// 过滤空 设置 TreeMap
				SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
				Iterator it = params.keySet().iterator();
				while (it.hasNext()) {
					String parameter = (String) it.next();
					String parameterValue = params.get(parameter)+"";
					String v = "";
					if (null != parameterValue) {
						v = parameterValue.trim();
					}
					System.out.println("value==============="+v);
					packageParams.put(parameter, v);
				}
				// 查看回调参数
				// LogUtil.writeMsgToFile(packageParams.toString());
//				String total_fee = new BigDecimal((String) packageParams.get("total_fee")).divide(new BigDecimal(100)).toString();
				// 账号信息
				String resXml = "";
				// ------------------------------
				// 处理业务开始
				// ------------------------------
				if ("SUCCESS".equals((String) packageParams.get("result_code"))) {

				    // 这里是支付成功
                    String prdOrdNo = String.valueOf(packageParams.get("out_trade_no"));

                    Map<String,Object> queryMap = new HashMap<String,Object>();
                    queryMap.put("prdOrdNo", prdOrdNo);
                    Map<String,Object> prdOrdMap = orderService.getPrdOrdMap(queryMap);

                    String ordStatus = (String)prdOrdMap.get("ordStatus");
                    if(MsgCT.ORDSTATUS_SUCCESS.equals(ordStatus)){//成功的订单不允许再更新
                        logger.warn("订单状态已成功，不允许更新...");
                        return;
                    }

                    String chlPayAmt = ObjectUtil.getString(params.get("total_fee"));
                    if(chlPayAmt.equals(prdOrdMap.get("txAmt").toString()) == false){
                        throw new BusinessException(ExcepCode.EX900000,"支付金额不一致 成功金额[{}] 订单支付金额[{}]",chlPayAmt,prdOrdMap.get("txAmt").toString());
                    }

                    //原交易大商户编号
                    String mchNo = (String)prdOrdMap.get("TMERCID");
                    if(StringUtils.isEmpty(mchNo)){
                        throw new BusinessException(ExcepCode.EX900000,"原交易商户号不能为空");
                    }

                    //定义回调订单信息Map
                    Map<String,Object> orderCallBackMap = new HashMap<String, Object>();
                    orderCallBackMap.put("prdOrdNo", prdOrdMap.get("prdOrdNo"));//订单号
                    orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_PROCESSING);
                    orderCallBackMap.put("resJson", com.acq.sdk.JsonUtil.toJson(params));

                    //支付成功
                    orderCallBackMap.put("ordStatus", MsgCT.ORDSTATUS_SUCCESS);

                    //调用回调更新订单
                    logger.info("通知平台更新订单[{}]",orderCallBackMap);
                    orderService.prdPayCallBack(orderCallBackMap);

					////////// 执行自己的业务逻辑////////////////
					// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
					resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
				} else {
					resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[充值失败]]></return_msg>" + "</xml> ";
				}

				// 返回
                respContent(response, resXml);

			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		} catch (Exception e){
			logger.error("[异步回调]异常:", e.getMessage(), e);
			return;
		}
		
		logger.info("微信H5[异步回调]完成");
	}

	public static String readData(HttpServletRequest request) {
		BufferedReader br = null;
		try {
			StringBuilder result = new StringBuilder();
			br = request.getReader();
			for (String line; (line=br.readLine())!=null;) {
				if (result.length() > 0) {
					result.append("\n");
				}
				result.append(line);
			}

			return result.toString();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		finally {
			if (br != null)
				try {br.close();} catch (IOException e) {e.printStackTrace();}
		}
	}

	private void respContent(HttpServletResponse response, String content)
			throws Exception {
		PrintWriter out = response.getWriter();
		out.write(content);
		out.flush();
		out.close();
	}
	
}
